<template>
  <div>
    <div class="search">
      <el-input placeholder="请输入分类名" style="width: 200px" v-model="categoriesName"></el-input>
      <el-select v-model="type" placeholder="请选择展示状态" style="margin-left: 10px">
        <el-option
            v-for="item in typeOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value">
        </el-option>
      </el-select>
      <el-select v-model="state" placeholder="请选择开启状态" style="margin-left: 10px">
        <el-option
            v-for="item in stateOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value">
        </el-option>
      </el-select>
      <el-button type="info" plain style="margin-left: 10px" @click="load(1)">查询</el-button>
      <el-button type="warning" plain style="margin-left: 10px" @click="reset">重置</el-button>
    </div>

    <div class="operation">
      <el-button type="primary" plain @click="handleAdd">新增</el-button>
      <el-button type="danger" plain @click="delBatch">批量删除</el-button>
    </div>

    <div class="table">
      <el-table :data="tableData" strip @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center"></el-table-column>
        <el-table-column label="序号" width="70" align="center" sortable>
          <template #default="{ row, $index }">
            {{ $index + 1 }} <!-- 这里是序号从1开始 -->
          </template>
        </el-table-column>
        <el-table-column label="图片">
          <template v-slot="scope">
            <div style="display: flex; align-items: center">
              <el-image style="width: 60px; height: 60px; border-radius: 80%"
                        :src="scope.row.imageUrl || defaultImageUrl"
                        :preview-src-list="[scope.row.imageUrl || defaultPreviewUrl]"></el-image>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="name" label="分类名"></el-table-column>
        <el-table-column label="是否展示" align="center" width="100">
          <template v-slot="scope">
            <el-switch
                v-model="scope.row.type"
                :active-value="1"
                :inactive-value="0"
                @change="updateTypeAndState(scope.row,0)">
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column label="是否开启" align="center" width="100">
          <template v-slot="scope">
            <el-switch
                v-model="scope.row.state"
                :active-value="0"
                :inactive-value="1"
                @change="updateTypeAndState(scope.row,1)">
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="130"></el-table-column>
        <el-table-column prop="createUserName" label="创建人"></el-table-column>
        <el-table-column prop="updateTime" label="修改时间" width="130"></el-table-column>
        <el-table-column prop="updateUserName" label="修改人"></el-table-column>
        <el-table-column label="操作" align="center" width="250">
          <template v-slot="scope">
            <el-button size="mini" type="primary" plain @click="addProduct(scope.row.id)">添加商品</el-button>
            <el-button size="mini" type="primary" plain @click="handleEdit(scope.row)">编辑</el-button>
            <el-button size="mini" type="danger" plain @click="del(scope.row.id)" >删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination">
        <el-pagination
            background
            @current-change="handleCurrentChange"
            :current-page="pageNum"
            :page-sizes="[5, 10, 20]"
            :page-size="pageSize"
            layout="total, prev, pager, next"
            :total="total">
        </el-pagination>
      </div>
    </div>

    <el-dialog title="分类" :visible.sync="fromVisible" width="40%" :close-on-click-modal="false" destroy-on-close @close="handleCancel">
      <el-form :model="form" label-width="100px" style="padding-right: 50px" :rules="rules" ref="formRef">
        <el-form-item label="分类名" prop="name">
          <el-input v-model="form.name" placeholder="分类名" maxlength="20"></el-input>
        </el-form-item>
        <el-form-item label="图片">
          <el-upload
              class="avatar-uploader"
              :action="$baseUrl + '/admin/api/photo/upload'"
              :headers="{ authentication: user.token }"
              :data="{ imageType: 'AVATAR'}"
              list-type="picture"
              :on-success="handleAvatarSuccess"
              :file-list="fileList"
              :on-remove="handleRemove"
          >
            <el-button type="primary">上传图片</el-button>
          </el-upload>
        </el-form-item>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button @click="handleCancel">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </div>
    </el-dialog>

    <el-dialog title="商品分类" :visible.sync="addProductForm" width="40%" :close-on-click-modal="false" destroy-on-close>
      <el-form :model="form" label-width="100px" style="padding-right: 50px; text-align: center" :rules="rules" ref="formRef">
        <el-input placeholder="请输入商品名" style="width: 200px; display: inline-block" v-model="productName"></el-input>
        <el-button type="info" plain style="margin-left: 10px" @click="selectProduct">查询</el-button>
        <el-form-item label="选择商品：" prop="selectedProducts">
          <el-checkbox-group v-model="products" @change="handleProductUnselect">
            <el-checkbox
                v-for="product in productData"
                :key="product.id"
                :label="product.id">
              {{ product.name }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button @click="addProductForm = false">取 消</el-button>
        <el-button type="primary" @click="saveProductCategories">确 定</el-button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
export default {
  name: "Categories",
  data() {
    return {
      //默认图片
      defaultImageUrl: 'https://img0.baidu.com/it/u=2991630058,871933297&fm=253&fmt=auto&app=138&f=JPEG?w=300&h=300',
      //默认预览
      defaultPreviewUrl: 'https://img0.baidu.com/it/u=2594677340,3536341249&fm=253&fmt=auto&app=138&f=JPG?w=240&h=240',
      tableData: [],  // 所有的数据
      productData: [], //所有商品数据
      products: [], //被选中的商品
      fileList: [], // 用于存储上传的文件列表
      stateOptions: [
        { value: 0, label: '开启' },
        { value: 1, label: '不开启' }
      ],
      typeOptions: [
        { value: 1, label: '展示' },
        { value: 0, label: '不展示' }
      ],
      categoriesId: null,
      pageNum: 1,   // 当前的页码
      pageSize: 10,  // 每页显示的个数
      total: 0,
      typeOneCount: 0, // 用于跟踪type为1的记录总数
      disableTypeOne: false, // 控制是否禁用将type改为1的操作
      categoriesName: null,
      productName:null,
      createUser: null,
      state: null,
      type: null,
      fromVisible: false,
      addProductForm: false,
      form: {},
      user: JSON.parse(localStorage.getItem('xm-user') || '{}'),
      rules: {
        name: [
          { required: true, message: '分类名不能为空', trigger: 'blur' },
          { min: 1, max: 20, message: '分类名长度在 1 到 20 个字符', trigger: 'blur' }
        ]
      },
      ids: [],
      previousSelectedProducts: [],
      previousProductData: [], // 保存添加商品对话框打开时的商品数据状态
    }
  },
  created() {
    this.load(1)
  },
  methods: {
    handleRemove(file, fileList) {
      // 删除图片时，更新fileList数组
      this.fileList = fileList;
    },
    updateTypeAndState(row,i) {
      // 发起请求更新数据
      this.$request.put('/admin/api/categories/update', row).then(res => {
        if (res.code !== 0) {
          // 如果更新失败，回显原来的状态
          if (i===0){row.type = row.type === 1 ? 0 : 1;}
          else{row.state = row.state === 0 ? 1 : 0;}
          this.$message.error(res.msg);
        } else {
          // 更新成功，可以在这里进行其他操作，比如通知用户
          this.$message.success('状态更新成功');
        }
      }).catch(error => {
        // 如果请求失败，回显原来的状态
        row.type = row.type === 1 ? 0 : 1;
        row.state = row.state === 0 ? 1 : 0;
        this.$message.error('网络错误或服务器无响应');
      });
    },
    // 更新type为1的记录总数
    updateTypeOneCount() {
      this.typeOneCount = this.tableData.filter(item => item.type === 1).length;
      this.disableTypeOne = this.typeOneCount >= 5;
    },
    selectProduct(){
      this.$request.get('/admin/api/product/pages', {
        params: {
          name: this.productName,
        }
      }).then(res => {
        this.productData = res.records
      })
    },
    handleAdd() {   // 新增数据
      this.form = {}  // 新增数据的时候清空数据
      this.fromVisible = true   // 打开弹窗
    },
    handleCancel(){
      this.fileList = []
      this.fromVisible = false
    },
    handleEdit(row) {
      this.fileList = []
      this.form = JSON.parse(JSON.stringify(row)); // 给form对象赋值，注意要深拷贝数据
      this.fileList = this.form.imageUrl ? [{name: 'current-image', url: this.form.imageUrl}] : []
      this.fromVisible = true; // 打开弹窗
    },
    addProduct(id) {
      this.categoriesId = id;
      this.productName = null
      this.selectProduct()
      // 调用后端接口获取所有商品分类关联数据
      this.$request.get('/admin/api/pcategories/all').then(res => {
        if (res.code === 0) {
          // 假设 res.data 是一个包含所有商品分类关联的数组
          // 筛选出与当前分类 id 相关的商品 id
          this.products = res.data
              .filter(item => item.categoriesId === id)
              .map(item => item.productId);
          // 打开对话框前保存当前的商品数据状态
          this.previousProductData = [...this.products];
          // 打开对话框
          this.addProductForm = true;
        } else {
          this.$message.error(res.msg);
        }
      }).catch(error => {
        this.$message.error('网络错误或服务器无响应');
      });
    },

    save() {
      // 在保存前检查是否禁用将type改为1的操作
      if (this.form.type === 1 && this.disableTypeOne) {
        this.$message.error('已达最大展示数量，无法设置为展示');
        return;
      }
      // 检查fileList是否为空，如果为空，则将imageUrl设置为null
      if (this.fileList.length === 0) {
        this.form.imageUrl = null;
      }
      // id不存在就直接返回 中间可以提醒用户
      this.$refs.formRef.validate((valid) => {
        if (valid) {
          this.$request({
            url: this.form.id ? '/admin/api/categories/update' : '/admin/api/categories/add',
            method: this.form.id ? 'PUT' : 'POST',
            data: this.form
          }).then(res => {
            if (res.code === 0) {  // 表示成功保存
              this.$message.success('保存成功')
              this.load(1) // 刷新页面
              this.fromVisible = false  // 关闭弹窗
            } else {
              this.$message.error(res.msg)  // 弹出错误的信息
            }
          })
        }
      })
    },

    // 跟踪被取消的商品
    handleProductUnselect(newVal) {
      // 找出被取消的商品ID
      const removedProducts = this.previousSelectedProducts.filter(x => !newVal.includes(x));
      // 更新之前选中的商品
      this.previousSelectedProducts = newVal.slice();
      // 这里不再直接删除，而是将 removedProducts 保存在数据属性中
      this.removedProducts = removedProducts;
    },

    // 删除被取消的商品分类关联
    deleteProductCategories(productIds) {
      // 构造要删除的商品分类关联ID列表
      const productCategoriesDTO = productIds.map(productId => ({
        productId: productId,
        categoriesId: this.categoriesId
      }));

      // 发送请求到服务器删除关联
      this.$request.delete('/admin/api/pcategories/delete/batch', {data: productCategoriesDTO}).then(res => {
        if (res.code === 0) {
        } else {
          this.$message.error(res.msg);
        }
      }).catch(error => {
        this.$message.error('网络错误或服务器无响应');
      });
    },

    saveProductCategories() {
      // 检查商品数据是否有变化
      if (this.products.length === this.previousProductData.length &&
          this.products.every((value, index) => value === this.previousProductData[index])) {
        // 数据没有变化，不执行任何操作
        this.addProductForm = false;
        return;
      }

      // 构造请求体，每个商品与分类的关联
      const productCategoriesDTO = this.products.map(productId => ({
        productId: productId,
        categoriesId: this.categoriesId
      }));

      // 如果有需要删除的商品分类关联，先执行删除操作
      if (this.removedProducts.length > 0) {
        this.deleteProductCategories(this.removedProducts);
      }

      // 发送请求到服务器添加关联
      this.$request({
        url: '/admin/api/pcategories/adds',
        method: 'POST',
        data: productCategoriesDTO
      }).then(res => {
        if (res.code === 0) {
          this.$message.success('操作成功');
          // 关闭弹窗
          this.addProductForm = false;
        } else {
          this.$message.error(res.msg);
        }
      }).catch(error => {
        this.$message.error(err.message);
      });
    },
    del(id) {   // 单个删除
      this.$confirm('您确定删除吗？', '确认删除', {type: "warning"}).then(response => {
        this.$request.delete('/admin/api/categories/delete/' + id).then(res => {
          if (res.code === 0) {   // 表示操作成功
            this.$message.success('操作成功')
            this.load(1)
          } else {
            this.$message.error(res.msg)  // 弹出错误的信息
          }
        })
      }).catch(() => {
      })
    },
    handleSelectionChange(rows) {   // 当前选中的所有的行数据
      this.ids = rows.map(v => v.id)
    },
    delBatch() {   // 批量删除
      if (!this.ids.length) {
        this.$message.warning('请选择数据')
        return
      }
      this.$confirm('您确定批量删除这些数据吗？', '确认删除', {type: "warning"}).then(response => {
        this.$request.delete('/admin/api/categories/delete/batch', {data: this.ids}).then(res => {
          if (res.code === 0) {   // 表示操作成功
            this.$message.success('操作成功')
            this.load(1)
          } else {
            this.$message.error(res.msg)  // 弹出错误的信息
          }
        })
      }).catch(() => {
      })
    },
    load(pageNum) {  // 分页查询
      if (pageNum) this.pageNum = pageNum
      this.$request.get('/admin/api/categories/pages', {
        params: {
          current: this.pageNum,
          size: this.pageSize,
          name: this.categoriesName,
          type: this.type,
          state: this.state,
        }
      }).then(res => {
        this.tableData = res.records
        this.total = res.total
        this.updateTypeOneCount() // 更新type为1的记录总数
        this.$request.get('/admin/api/product/pages', {
        }).then(res => {
          console.log(res.records)
          this.productData = res.records
        }).catch(error => {
        })
      })
    },
    reset() {
      this.categoriesName = null
      this.currentState = null; // 重置当前状态
      this.state = null
      this.type = null
      this.load(1)
    },
    handleCurrentChange(pageNum) {
      this.load(pageNum)
    },
    handleAvatarSuccess(response, file, fileList) {
      // 定义一个正则表达式来匹配允许的文件扩展名
      const allowedExtensions = /.(png|jpg|jpeg)$/i;

      // 检查文件扩展名是否为允许的格式
      if (!allowedExtensions.test(file.name)) {
        // 如果文件扩展名不允许，从fileList中移除
        this.fileList = fileList.filter(f => f.uid !== file.uid);
        // 发出提示
        this.$message.error('只能上传png, jpg, jpeg格式的图片！');
        return; // 不进行后续操作
      }

      // 如果文件扩展名允许，更新imageUrl和fileList
      this.form.imageUrl = response.data;
      this.fileList = fileList; // 更新fileList
    },
  },
  watch: {
    // 当对话框打开时，初始化之前选中的商品
    addProductForm(val) {
      if (val) {
        this.previousSelectedProducts = this.products.slice();
      }
    }
  },
}
</script>

<style scoped>

</style>